﻿using DivaScript;
using MikuMikuModel.Logs;
using Newtonsoft.Json;
using ScriptUtilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace DivaScriptConv
{
    class PvCmds
    {
        public List<PvCmd> pvCommands = new List<PvCmd>();
        public void Load(List<PvCommand> _pv)
        {
            int curTime = 0;
            foreach (var cmd in _pv)
            {
                if (cmd.Opcode == "TIME")
                {
                    curTime = cmd.Parameters[0];
                    if (curTime == -1)
                        curTime = 0;
                }
                else
                {
                    var find = pvCommands.Where(c => c.Time == cmd.TimeStamp).FirstOrDefault();
                    if (find == null)
                    {
                        pvCommands.Add(new PvCmd(cmd.TimeStamp));
                        find = pvCommands.Where(c => c.Time == cmd.TimeStamp).First();
                    }
                    find.Add(cmd);
                }
            }
        }
        public void RemoveOpcode(string opcode)
        {
            foreach (var i in pvCommands)
            {
                foreach (var c in i.pvCommands.ToList())
                {
                    if (c.Opcode == opcode)
                        i.pvCommands.Remove(c);
                }
            }
        }

        public void Insert(int curTime, PvCommand cmd)
        {
            cmd.TimeStamp = curTime;
            var find = pvCommands.Where(c => c.Time == curTime).FirstOrDefault();
            if (find == null)
            {
                pvCommands.Add(new PvCmd(curTime));
                find = pvCommands.Where(c => c.Time == curTime).First();
            }
            if (cmd.Opcode == "CHANGE_FIELD")
            {
                if (find.pvCommands.Where(c => c.Opcode == "CHANGE_FIELD").Where(d => d.Parameters.Count == 1).Any())
                {
                    //Logs.WriteLine("DSC: DUPE CHANGE_FIELD AT " + find.Time);
                }
                else
                {
                    find.Add(cmd);
                }
            }
            else find.Add(cmd);
        }

        public void Insert(PvCommand cmd, int curTime)
        {
            cmd.TimeStamp = curTime;
            var find = pvCommands.Where(c => c.Time == curTime).FirstOrDefault();
            if (find == null)
            {
                pvCommands.Add(new PvCmd(curTime));
                find = pvCommands.Where(c => c.Time == curTime).First();
            }
            if (cmd.Opcode == "CHANGE_FIELD")
            {
                if (find.pvCommands.Where(c => c.Opcode == "CHANGE_FIELD").Where(d => d.Parameters.Count == 1).Any())
                {
                    //Logs.WriteLine("DSC: DUPE CHANGE_FIELD AT " + find.Time);
                }
                else
                {
                    find.Add(cmd);
                }
            }
            else find.Add(cmd);
        }
        public void Insert(PvCommand cmd, int curTime, int At)
        {
            cmd.TimeStamp = curTime;
            var find = pvCommands.Where(c => c.Time == curTime).FirstOrDefault();
            if (find == null)
            {
                pvCommands.Insert(At, new PvCmd(curTime));
                find = pvCommands.Where(c => c.Time == curTime).First();
            }
            if (cmd.Opcode == "CHANGE_FIELD")
            {
                if (find.pvCommands.Where(c => c.Opcode == "CHANGE_FIELD").Where(d => d.Parameters.Count == 1).Any())
                {
                    Logs.WriteLine("DSC: DUPE CHANGE_FIELD AT " + find.Time);
                }
                else
                {
                    find.Add(cmd);
                }
            }
            else find.Add(cmd);
        }
        public List<PvCommand> Export()
        {
            var _pv = new List<PvCommand>();

            foreach (var cmds in pvCommands.OrderBy(c => c.Time))
            {
                if (cmds.pvCommands.Count != 0)
                {
                    if (cmds.Time >= 0)
                        _pv.Add(new PvCommand(cmds.Time, "TIME", cmds.Time));
                    foreach (var cmd in cmds.pvCommands)
                    {
                        cmd.TimeStamp = cmds.Time;
                        _pv.Add(cmd);
                    }
                }
            }

            return _pv;
        }
    }
}
